//
//  HFHotKeyController.h
//  HocusFocus
//
//  Created by Juan Carlos Jimenez on 4/1/06.
//  Copyright 2008 Juan Carlos Jimenez. All rights reserved.
//
#import "HFHotKeyController.h"
#import "HFPreferencesController.h"

#define kHFNumber1Key 0x12
#define kHFNumber2Key 0x13
#define kHFNumber3Key 0x14
#define kHFNumber4Key 0x15
#define kHFNumber5Key 0x17
#define kHFNumber6Key 0x16
#define kHFNumber7Key 0x1a
#define kHFNumber8Key 0x1c
#define kHFNumber9Key 0x19
#define kHFNumber0Key 0x1d

#define kMWF1Key 0x7a
#define kMWF2Key 0x78
#define kMWF3Key 0x63
#define kMWF4Key 0x76
#define kMWF5Key 0x60
#define kMWF6Key 0x61
#define kMWF7Key 0x62
#define kMWF8Key 0x64
#define kMWF9Key 0x65
#define kMWF10Key 0x6d
#define kMWF11Key 0x67
#define kMWF12Key 0x6f
#define kMWF13Key 0x69

#define kHFPrefKeyModifierCommand @"modifierCommand"
#define kHFPrefValueModifierCommand @"1"

#define kHFPrefKeyModifierControl @"modifierControl"
#define kHFPrefValueModifierControl @"0"

#define kHFPrefKeyModifierShift @"modifierShift"
#define kHFPrefValueModifierShift @"1"

#define kHFPrefKeyHotkey @"hotkey"

 /* This is the index of the key drop-down, this is bad and will be changed in the next rev. */
#define kHFPrefValueHotkey @"4"

const UInt32 kHFHotKeyArray[] = {
									kHFNumber1Key,
									kHFNumber2Key,
									kHFNumber3Key,
									kHFNumber4Key,
									kHFNumber5Key,
									kHFNumber6Key,
									kHFNumber7Key,
									kHFNumber8Key,
									kHFNumber9Key,
									kHFNumber0Key,

									kMWF1Key,
									kMWF2Key,
									kMWF3Key,
									kMWF4Key,
									kMWF5Key,
									kMWF6Key,
									kMWF7Key,
									kMWF8Key,
									kMWF9Key,
									kMWF10Key,
									kMWF11Key,
									kMWF12Key,
									kMWF13Key,
									0
								};
								
const int kHFMaxHotKeyIndex = 23;

@interface HFHotKeyController(Private)
- (UInt32)keycode;
- (UInt32)modifierMask;
@end

@implementation HFHotKeyController

+ (NSDictionary*) defaultsDict {
	NSMutableDictionary *appDefaults = [NSMutableDictionary dictionaryWithCapacity:4];
	
	[appDefaults setObject:kHFPrefValueModifierCommand forKey:kHFPrefKeyModifierCommand];
	[appDefaults setObject:kHFPrefValueModifierControl forKey:kHFPrefKeyModifierControl];
	[appDefaults setObject:kHFPrefValueModifierShift forKey:kHFPrefKeyModifierShift];
	[appDefaults setObject:kHFPrefValueHotkey forKey:kHFPrefKeyHotkey];

    return appDefaults;
}

- (id)init {
	self = [super init];
	if (self != nil) {
		hotKeyID.signature = 'HtKe';
		hotKeyID.id = 1;
	}
	return self;
}

- (void)dealloc {
	[self unregisterHotKey:nil];
	[super dealloc];
}

- (void)awakeFromNib {
	[self registerHotKey:nil];
}

- (void)registerHotKey:(id)sender
{
	OSStatus status = RegisterEventHotKey(
											[self keycode],
											[self modifierMask],
											hotKeyID,
											GetApplicationEventTarget(),
											0,
											&hotKeyRef
										);
	if (status != noErr)
	{
		NSLog(@"HFController: Could not register hotkey.  Got OSStatus: %d", status);
		exit(-1);
	}
}

- (void)unregisterHotKey:(id)sender
{
	OSStatus status = UnregisterEventHotKey(hotKeyRef);
	if (status != noErr)
	{
		NSLog(@"HFController: Could not unregister hotkey.  Got OSStatus: %d", status);
	}
}

- (void)updateHotKey:(id)sender
{
	[self unregisterHotKey:sender];
	[self registerHotKey:sender];
}

@end

@implementation HFHotKeyController(Private)

- (UInt32)keycode
{
	int keycodeIndex = [[[NSUserDefaultsController sharedUserDefaultsController] defaults] integerForKey:kHFPrefKeyHotkey];
	if (keycodeIndex < 0)
	{
		keycodeIndex = 0;
	}
	else if (keycodeIndex > kHFMaxHotKeyIndex)
	{
		keycodeIndex = kHFMaxHotKeyIndex;
	}
	return kHFHotKeyArray[keycodeIndex];
}

- (UInt32)modifierMask
{
	UInt32 modifiersMask = 0;
	if ([[[NSUserDefaultsController sharedUserDefaultsController] defaults] boolForKey:kHFPrefKeyModifierCommand])
	{
		modifiersMask |= cmdKey;
	}
	if ([[[NSUserDefaultsController sharedUserDefaultsController] defaults] boolForKey:kHFPrefKeyModifierControl])
	{
		modifiersMask |= controlKey;
	}
	if ([[[NSUserDefaultsController sharedUserDefaultsController] defaults] boolForKey:kHFPrefKeyModifierShift])
	{
		modifiersMask |= shiftKey;
	}
	return modifiersMask;	
}

@end
